\subsection{Events}\label{subsec:events}
The event\index{event} mechanism provided by the Muen kernel is used for
inter-subject signalization. A subject is allowed to send an event to another
subject if this operation has been granted by an entry in the subject's policy
event table. The following listing is used as an example to illustrate the
event mechanism.

\lstinputlisting[
	language=xml,
	label=lst:event-table,
	caption=Subject event table]
	{lst_event_table}

This event table in the system policy allows the associated subject to send two
events of different type to subjects \emph{s2} and \emph{s3} respectively. A
handover event transfers execution to a destination subject, optionally
injecting an interrupt.  Interrupt events inject an interrupt in a destination
subject, emitting an optional inter-processor interrupt (IPI)\index{IPI} to
speed up inter-core interrupt delivery.

Interrupts are injected into the destination subject by the Muen kernel to
inform it about new pending events. In this example, interrupt vector 33 is
injected into subject s2 for the interrupt event and no interrupt is delivered
for the handover event.

If the IPI option is enabled for an interrupt event, the Muen kernel sends an
inter-processor interrupt to the logical CPU of the destination subject. The
IPI causes the target processor to trap into the kernel, which results in the
preemption of the running subject and therefore the immediate delivery of the
interrupt on next subject entry. The event IPI option is only valid if the
destination subject runs on a different logical CPU than the sending subject.
This is enforced by the policy compiler.

To signal an event, subjects implemented in Ada or SPARK can use the
\texttt{SK.Hypercall} package provided by Muen. The package contains the
procedure \texttt{Trigger\_Event} which accepts the event number as its sole
argument. The procedure wraps the \texttt{VMCALL} VMX instruction, which causes
a trap into the kernel when called from VMX non-root mode. This is used by the
Muen kernel to implement the hypercall mechanism.  With the Intel VMX
extensions, a hypercall is a special trap with basic exit reason number 18. The
event number call argument is passed via the RAX CPU register.

The Muen kernel handles hypercall traps separately in the
\texttt{Handle\_Hypercall} procedure. It performs a lookup in the sending
subject's event table to find the associated event entry. If no such entry
exists, the kernel logs an error message (in debug mode only) and ignores the
event. Valid events of type interrupt are injected using the VMX interrupt
injection capabilities.

If the event is of type handover, the sending subject is replaced by the
destination subject in the scheduling plan. The destination subject is then
executed in place of the sending subject until it yields the CPU in favor of
another subject. This method can be used to implement co-operative scheduling
in subject groups.

\begin{figure}[h]
	\centering
	\input{graph_events}
	\caption{Inter-core events}
	\label{fig:inter-core-events}
\end{figure}

The event mechanism in general can be utilized to realize low-latency
communication channels between subjects, as illustrated in figure
\ref{fig:inter-core-events}. In this example, two subjects running on different
logical CPUs (CPU0, CPU1) implement a simple request-response design:

\begin{enumerate}
	\item The requesting subject on the left (client) running on CPU0 writes
		the request data into a memory page shared with the service provider
		subject on the right (server). It then signals a pending request to the
		server subject by sending an event (i.e. it calls the
		\texttt{Trigger\_Event} procedure).

		The event lets the processor trap into the kernel. Since the subjects
		run on different cores in parallel, interrupt events must be used in
		this example. The \texttt{Handle\_Hypercall} procedure in the kernel
		checks if the event is valid and inserts it into the destination
		subject's pending event list. If the IPI option is enabled, the kernel
		also sends an IPI to the target CPU1.
	\item The IPI causes a trap on the destination CPU1. The interrupt
		event is therefore immediately injected into the destination subject on
		the next VMX entry.

		The server subject is waiting for data so it might be in a halted
		state.  The injected interrupt resumes the server subject which then
		reads the request data from the (read-only) request page and calculates
		the result. It writes the result data into the response page shared
		with the client subject.
	\item The server subject signals completion by triggering an event, which
		again leads to a trap into the kernel. The kernel inserts the event in
		the pending event list of the client subject and (if enabled) sends an
		IPI to CPU0.
	\item The pending event is injected into the client subject. The subject
		might be in a halted state because it is waiting for the result. The
		injected interrupt resumes the subject and the service result can be
		copied from the response page shared with the server.
\end{enumerate}
